package kino.timeevent;

import kino.server.KinoServer;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.CountDownLatch;

/**
 * 时间事件抽象类 TODO 开发中用于执行周期性定时时间
 */
public abstract class TimeEvent implements Runnable {

    /**
     * 时间时间最后执行时间
     */
    private Long lastExecutionEventTime;

    /**
     * 时间事件周期参数如 1000 则 每秒执行一次
     */
    private Long interval;

    /**
     * 执行次数统计
     */
    private Integer executeCount;

    private Long timeCount;

    /**
     * 临时同步器
     */
    private CountDownLatch timeEventLoading;

    @Autowired
    protected KinoServer kinoServer;

    TimeEvent(Long lastExecutionEventTime, Long interval) {
        this.interval = interval;
        this.lastExecutionEventTime = lastExecutionEventTime;
        this.executeCount = 0;
        this.timeCount = 0L;
    }
    TimeEvent(Long interval) {
        this(System.currentTimeMillis(), interval);
    }

    private Long getNextExecutionEventTime() {
        return lastExecutionEventTime + interval;
    }

    @Override
    public void run() {
        // 事件起始事件
        Long curBeginTime = System.currentTimeMillis();
        // 事件执行
        this.doTimeEventExecute();
        // 事件结束事件
        Long curEndTime = System.currentTimeMillis();
        // 最后执行时间更新
        this.lastExecutionEventTime = curEndTime;
        // 执行次数增加
        this.executeCount++;
        // 执行时间统计
        this.timeCount += curEndTime - curBeginTime;
        // 同步器释放资源
        if (timeEventLoading != null) {
            timeEventLoading.countDown();
            timeEventLoading = null;
        }
    }

    public Long getLastExecutionEventTime() {
        return lastExecutionEventTime;
    }

    public void setLastExecutionEventTime(Long lastExecutionEventTime) {
        this.lastExecutionEventTime = lastExecutionEventTime;
    }

    public Long getInterval() {
        return interval;
    }

    public void setInterval(Long interval) {
        this.interval = interval;
    }

    public CountDownLatch getTimeEventLoading() {
        return timeEventLoading;
    }

    public void setTimeEventLoading(CountDownLatch timeEventLoading) {
        this.timeEventLoading = timeEventLoading;
    }

    /**
     * 执行时间事件
     */
    abstract void doTimeEventExecute();
}
